/*
  Program: Mine Mayhem
  File:    fieldhxr.cc
  Date:    26 October to 3 December,	      version 2.00
	   8 December to 4 January,  2001,    version 2.10
	   15 January,			      version 2.11
	   18 September to 16 December, 2006, version 2.90

  Everything to do with the hex-tiled rectangular minefield.

  Freeware, Copyright 2006 Jason Hood.
*/

#include "minefld.h"
#include "options.h"
#include "tiles.h"
#include "board.h"


RectHexField::RectHexField() : SquareField(false)
{
  MaxWidth  = max_cols = (max_width / HEXAGONW) - 1;
  MaxHeight = max_rows = (max_height - HEXAGOND) / HEXAGONR;

  CreateMinefield();
}


/* -----------------------------   EveryTile   ------------------------------

  Create the list of hexagons on the minefield.

*/

void RectHexField::EveryTile()
{
  SquareField::EveryTile();

  foralltiles
  {
    Tile& t = field[tile];
    t.loc.x = t.grid.x * HEXAGONW + HEXAGONW/2 * (t.grid.y & 1);
    t.loc.y = t.grid.y * HEXAGONR;
  }

  pan_wid = layout.dim.x * HEXAGONW - HEXAGONW/2;
}


/* ------------------------------   Surround   ------------------------------

  Determine the surrounding hexagons, where the order is:

     6 4     which is stored as:  6 4	    6 4
    5 0 2	      Even lines  5 0 2   5 0 2  Odd lines
     3 1			  3 1	    3 1

  This is to reduce opening hexagons in the cross game.

*/

void RectHexField::Surround(Tile* t)
{
  static cCoord ofsevn[] = { Coord( 0, 0), Coord( 0,+1),
			     Coord(+1, 0), Coord(-1,+1), Coord( 0,-1),
			     Coord(-1, 0), Coord(-1,-1) };

  static cCoord ofsodd[] = {		   Coord( 0, 0), Coord(+1,+1),
			     Coord(+1, 0), Coord( 0,+1), Coord(+1,-1),
					   Coord(-1, 0), Coord( 0,-1) };

  Minefield::Surround(t, 7, (t->grid.y & 1) ? ofsodd : ofsevn);
}


/* -------------------------   GetBoardDimensions   -------------------------

  Given the dimensions of the minefield, return the dimensions of the board.

*/

Coord RectHexField::GetBoardDimensions(cCoord& dim)
{
  return Coord(dim.x * HEXAGONW + HEXAGONW/2, dim.y * HEXAGONR + HEXAGOND);
}


/* ------------------------------   Outline   -------------------------------

  Draw the outline around the minefield.

*/

void RectHexField::Outline(ViewBuffer* buf, int x1, int y1, int x2, int y2)
{
  int lx = x1, rx = x2 - HEXAGONW,
      ty = y1, by = y1;

  // Left side.
  for (int y = 0; y < layout.dim.y/2; ++y)
  {
    BitBltTransparent(buf, lx, ty, Hexagon[HEXOUTLINE1],
		      HEXAGONW/2-1, 0, HEXAGONW-1, HEXAGONR);
    BitBltTransparent(buf, lx, ty+HEXAGONR+1, Hexagon[HEXOUTLINE2],
		      HEXAGONW/2-1, HEXAGONR-HEXAGOND, HEXAGONW-1, HEXAGONR);
    BitBltTransparent(buf, lx+HEXAGONW/2, ty+HEXAGONH+1, Hexagon[HEXOUTLINE2],
		      HEXAGONW/2-1, 0, HEXAGONW/2-1, HEXAGONR-1);
    ty += HEXAGONR*2;
  }
  if (layout.dim.y & 1)
  {
    BitBltTransparent(buf, lx, ty, Hexagon[HEXOUTLINE1],
		      HEXAGONW/2-1, 0, HEXAGONW-1, HEXAGONR);
    ty += HEXAGONR;
  }
  else
    lx += HEXAGONW/2;
  BitBltTransparent(buf, lx, ty+1, Hexagon[HEXOUTLINE2],
		    HEXAGONW/2-1, HEXAGONR-HEXAGOND, HEXAGONW-1, HEXAGONR);

  // Right side.
  BitBltTransparent(buf, rx, by, Hexagon[HEXOUTLINE1],
		    0, 0, HEXAGONW/2, HEXAGONR);
  rx += HEXAGONW/2; by += HEXAGONR;
  for (int y = 0; y < (layout.dim.y-1)/2; ++y)
  {
    BitBltTransparent(buf, rx, by+HEXAGOND+1, Hexagon[HEXOUTLINE2],
		      0, 0, HEXAGONW/2, HEXAGONR);
    BitBltTransparent(buf, rx, by+HEXAGONH+1, Hexagon[HEXOUTLINE2],
		      HEXAGONW/2, 0, HEXAGONW/2, HEXAGONR);
    by += HEXAGONR*2;
  }
  if (layout.dim.y & 1)
  {
    BitBltTransparent(buf, rx-HEXAGONW/2, by+1, Hexagon[HEXOUTLINE2],
		      0, HEXAGONR-HEXAGOND, HEXAGONW/2, HEXAGONR);
    rx = 0;
  }
  else
  {
    BitBltTransparent(buf, rx, by+HEXAGOND+1, Hexagon[HEXOUTLINE2],
		      0, 0, HEXAGONW/2, HEXAGONR);
    rx = HEXAGONW/2;
  }

  lx = x1+1 + HEXAGONW/2; rx += lx;
  ty = y1;		  by = y2 - HEXAGOND;
  for (int x = 1; x < layout.dim.x; ++x)
  {
    // Top
    BitBltTransparent(buf, lx, ty, Hexagon[HEXOUTLINE1],
		      0, 0, HEXAGONW-1, HEXAGOND);
    // Bottom
    BitBltTransparent(buf, rx, by, Hexagon[HEXOUTLINE2],
		      0, HEXAGONR-HEXAGOND, HEXAGONW-1, HEXAGONR);
    lx += HEXAGONW;
    rx += HEXAGONW;
  }
}


/* ------------------------------   Convert   -------------------------------

  Convert the mouse co-ordinate to a grid co-ordinate.

*/

void RectHexField::Convert(int& x, int& y)
{
  int c, r;

  r  = y % HEXAGONR;
  y /= HEXAGONR;

  if (y & 1)
    x -= HEXAGONW/2;
  if (x < 0)
  {
    c = x + HEXAGONW;
    x = -1;
  }
  else
  {
    c  = x % HEXAGONW;
    x /= HEXAGONW;
  }

  if (r < HEXAGOND)
  {
    r = HexMask[r][c];
    if (r)
    {
      --y;
      if (y & 1)
      {
	if (r == 1)
	  --x;
      }
      else if (r == 2)
	++x;
    }
  }
}


/* ----------------------------   DisplayTile	-----------------------------

  Display the hexagon t using which bitmap.

*/

void RectHexField::DisplayTile(Tile* t, int which)
{
  Minefield::DisplayTile(t, which, HEXAGONW-1, HEXAGONH-1, Hexagon);
}


/* -------------------------   ReadIni & WriteIni   -------------------------

  As you can see, it uses the "[ Hexagons ]" section and times are kept in
  the "minehxr.tym" file.

*/

void RectHexField::ReadIni(IniFile& ini)
{
  Minefield::ReadIni(ini, "Hexagons", "minehxr.tym");
}

void RectHexField::WriteIni(IniFile& ini)
{
  Minefield::WriteIni(ini, "Hexagons", "minehxr.tym");
}
